<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <title>Shitty editor - jsFiddle demo by r4z0rw0lf</title>
  
  
  <style type='text/css'>
    .numbered_textarea table {
    width: 100%;
    heigth: 100%;
    position: absolute;
    left: 0px;
    top: 0px;
    
}
tr.currentLine {
    background: #073642 !important;
}
.numbered_textarea table tr  td.lineNumber {
    min-width: 2.5em !important;
    max-width: 2.5em !important;
    width: 2.5em !important;
    vertical-align: top;
    overflow-y:hidden;
    font-family: monospace;
    border-right: 1px solid #aaa;
    text-align: center;
    color: #586e75;
    background: #073642;
}
.numbered_textarea table tr td.line {
    /* 268 */
    /*width: 268px !important;*/
    max-width: 500px !important;
    word-wrap:break-word;
    padding: 0;
    margin: 0;
    white-space: pre-wrap;
    overflow-y:scroll;
    overflow-x: hidden;
    color: #93a1a1;
}
.numbered_textarea {
    outline: 1px solid #aaa;
    letter-spacing: 0;
    width: 100%;
    height: 100%;
    position: relative;
    overflow: hidden;
    background: #002b36;
}
.numbered_textarea textarea {
    border: 0px solid transparent;
    border-left: 1px solid #777;
    position: absolute;
    left: 2.5em;
    top: 0;
    width:-moz-calc(100% - 2.5em);
    height: 100%;
    bottom: 0;
    right: 0;
    background: rgba(255,255,255,0);
    -webkit-appearance: none;
    overflow-y: scroll;
    color: rgba(255,255,255,0.1);
    resize: none;
    outline: none;
}
.numbered_textarea * {
    font-family: monospace;
    font-size: 11pt;
    line-spacing: 0;
}
html, body {
    height: 100%;
}


.base03{
    color: #002b36;
}
.base02 {
    color: #073642;
}
.base01, .base01 * {
    color: #586e75 !important;
}
.base00 {
    color: #657b83;
}
.base0 {
    color: #839496;
}
.base1 {
    color: #93a1a1;
}
.base2 { 
    color: #eee8d5;
}
.base3 {
    color: #fdf6e3;
}
.yellow {
    color: #b58900;
}
.orange {
    color: #cb4b16;
}
.red {
    color: #dc322f;
}
.magenta {
    color: #d33682;
}
.violet {
    color: #6c71c4;
}
.blue {
    color: #268bd2;
}
.cyan, .cyan * {
    color: #2aa198;
}
.green {
    color: #859900;
}
  </style>
  


<script type='text/javascript'>//<![CDATA[ 
window.onload=function(){
configuration = {
    tabwidth: 4,
    
};
areas = document.querySelectorAll(".numbered_textarea");
function htmlEntities(str) {
    return String(str).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
}
function pad(str, length, character){ while(str.length < length){str = character+str;} return str; }

var highlight = function(str){
    for(regex in highlight.syntax){
        str = str.replace(new RegExp(regex, "g"),"<span class=\""+ highlight.syntax[regex] + "\">$1</span>");
        //str = str.replace(new RegExp(regex, "g"),"$1".replace(");
    }
    return str;
};
highlight.syntax = {
    "\\b(var )": "blue",
    "\\b(function\\b)":"blue",
    "\\b(if|for|while|do|switch|case|new|try|catch|throw|document|window|undefined)\\b": "yellow",
    "\\b(String|Array|Object|Function|Math)\\b":"orange",
    "\\b(this)\\b":"cyan",
    "(&quot;(?:\\\\?.)*?&quot;)":"cyan",
    "('(?:\\\\?.)*?')":"cyan",
    "(//.*)":"base01",
    "\\b(console\.error)\\b": "red",
    "\\b(console\.(warn|assert))\\b": "yellow",
    "\\b(console\.(log|info))\\b": "green",
    "\\b(console\.)\\b": "base1",
    "\\b([0-9]+|0x[0-9a-fA-F]+)\\b": "violet",
};
[].slice.call(areas).forEach(function(area){
    textarea = document.createElement("textarea");
    table = document.createElement("table");
    var content = area.innerHTML;
    area.innerHTML = "";
    area.appendChild(table);
    area.appendChild(textarea);
    textarea.addEventListener("keyup", textarea.process = function(e){
        table.innerHTML = "";
        lines = this.value.split('\n');
        lines.forEach(function(lineText, index){
            line = document.createElement("tr");
            number=document.createElement("td");
            number.className = "lineNumber";
            text  = document.createElement("td");
            text.className = "line";
            number.innerHTML = pad(index.toString(), 4, "0");
            //TODO: html entities
            text.innerHTML = highlight(htmlEntities(lineText))+" ";
            line.appendChild(number);
            line.appendChild(text);
            table.appendChild(line);
        });
        
    }, false);
    textarea.value = content;
    textarea.process.call(textarea);
    textarea.addEventListener("scroll", function(e){
            table.style.top = (-textarea.scrollTop)+"px";
    }, false);
    var setCurrentLine = function (e){
        
        currentLine =(textarea.value.substr(0,textarea.selectionStart).split('\n').length||1)-1;
        [].slice.call(table.querySelectorAll("tr.currentLine")).forEach(function(e){
            e.className = "lineNumber";
        });
        if(tr = table.querySelectorAll("tr")[currentLine])
            tr.className += " currentLine";
    };
    textarea.addEventListener("keyup", setCurrentLine);
    textarea.addEventListener("mouseup", setCurrentLine);
    textarea.addEventListener("keydown", function(e){
        if(e.keyCode === 9){
            e.preventDefault();
            tab = pad("", configuration.tabwidth, " ");
            var selS = this.value.substr(0, this.selectionStart),
                selE = this.value.substr(this.selectionEnd,this.value.length);
            this.value = selS + tab + selE;
            this.setSelectionRange(selS.length+tab.length, selS.length+tab.length);
            //this.selectionStart = selS.length+4;
        }
    }, false);
});
}//]]>  

</script>


</head>
<body>
  <div class="numbered_textarea"
>// Test for syntax highlighting....
var F = function(params){
    console.log(params);
    if(!params){
        throw "Error! No params!";
    }
    this.x = params.str || 'no such param \'str\'!';
};
try {
    var D = new F({asdf: "stringz!\"whoop!\" woo"});
}catch(error){
    console.error(error);
}
</div>
  
</body>


</html>
